package test

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
	"testing"
)

func Sign(content, prvKey []byte) (sign string, err error) {

	block, _ := pem.Decode(prvKey)

	if block == nil {
		fmt.Println("pem.Decode err")
		return
	}

	var private interface{}
	private, err = x509.ParsePKCS8PrivateKey(block.Bytes)

	if err != nil {
		return
	}

	privateKey := private.(*rsa.PrivateKey)
	h := crypto.Hash.New(crypto.SHA256)
	h.Write([]byte(content))
	hashed := h.Sum(nil)

	signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed)

	if err != nil {
		return
	}

	sign = base64.StdEncoding.EncodeToString(signature)

	return

}

func RSAVerify(origdata, cipertext string, publicKey []byte) (bool, error) {

	block, _ := pem.Decode(publicKey)

	if block == nil {
		return false, errors.New("public key error")
	}

	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)

	if err != nil {
		return false, err
	}

	pub := pubInterface.(*rsa.PublicKey)
	h := crypto.Hash.New(crypto.SHA256)
	h.Write([]byte(origdata))
	digest := h.Sum(nil)
	body, err := base64.StdEncoding.DecodeString(cipertext)

	if err != nil {
		return false, err
	}

	err = rsa.VerifyPKCS1v15(pub, crypto.SHA256, digest, body)
	if err != nil {
		return false, err
	}

	return true, nil

}

// 参考：Golang Java RSA SHA1withRSA 加签、验签
// https://www.jianshu.com/p/71c8cca8e4fa

func Test_SearchConfig(t *testing.T) {
	//pubKey := "-----BEGIN PUBLIC KEY-----\n{公钥内容}\n-----END PUBLIC KEY-----"
	//prvKey := "-----BEGIN RSA PRIVATE KEY-----\n{公钥内容}\n-----END RSA PRIVATE KEY-----"

	prvKey := "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDHhee3L++tf1qL\nUkXt5MyHsEiBK1D+fcNnJv/xrG1FNXXlUofQ6gCt6DSC/QAohbt4ppwJtR5X7+Sj\n72xhDrj2d9pegyMl5Nvfy9xBIaSh3HtpfrrhuLMNgqYrjSV6ARPUhyxZPBbCYhSu\n82rRjA8PSx2Mh2u8QlDNdLQaqbxKr6eoDYWls+zuVWZF2uFUPfRo6c8hFPYdB/oQ\ntkKyzHJWUinNgDBjeXrBfJ/roBpdr2FqjbwE24kKm0Fp/ZS1DwK3+TgxJfuvu8W3\ny6wgMEu9gv30sZGYrVO6tOpZyt2oWYUXy8IZilEWUBqNi/lsJRMogCRQC/1aDSYl\nm07RVjrbAgMBAAECggEABhI0LaChnY5hU27ynh1W/zlPziUNcbOi9VRm96lu/mr0\n25WqI02+LTctGIqZQs0QRMi7uRc6mqNmj3nIEEtR49IGzNcXA96rCsFvF3OYyQIR\nUUb1acvkdYtIV3fpMDAF30gpAyLEcIVqgAj7yETc6nK3LfZVmA9j2l9BjF7Q0hbo\nyWxmP0Am8XcZ+Ds+aBFj1mizNL8Fd8LS1QYP0d9mISd4d4oNP5lsKdvKizsS5MRl\nxWbYPH5Q5ydanbpTcpeydnZCWJzCnBkU9FyzzqTi/fWCYgX0v/iUUmL21APACwlL\naghhgIYp5anHuA9nA8LeHsJkujKmyZgrKoMP5yVfhQKBgQDn2LjACJxpGIuh3JEh\nkfYm6iCInDQ6+yduB2UKpJqW8+0DyEXY5Z+EpSDpVPU4E3ukeFWT1C0bFqYVuz9b\n+d6yBoNXxSWUG2vQePa7v8MD6kgpK8hsD097tULVLt9+UZfDnZm/oYV/QCcpE0dF\n4UBco6AZItABKoUeM5ML81ydHwKBgQDcTyAYWmSUNYy7yfKxiJS2DMjwlEvf8IXG\nOyPhTdydtwuSBlwGRoAF0mufb3+KpuTTX47gqeGqCTwghmBxZceeZ0u1ecnGMCfb\nCvhDU4WRkxtK8wROOCCixYrqvhyuozQJaRrl1Qa2bfCfmGDDT8VMQGK7BDv3MLa5\n0+uqgLJuxQKBgQDWSvOg05S2czCEwFkIvV/WYisF+dMw/PlZ8s3Kw4/7nKRjDZa5\nvqvtr6823Ab3+NIcl/kJdWDnm8yRY4xRmCflRq3Zz2hHd/z0KQptSPaYxNBD9ar/\nbjtaLZUDdJqwp/vtm9sDS+kXUBWiGqaTCXsy5S5SbWHy4fk+jA8LSbo9owKBgQCX\nz05meaNlHaFkpbw+6cbPy++LGCVQowULnCUVU/n6E/A9J3SyPlJpsJ3It6RDfs2f\nefGSjn2aFdMA9pfujBwJ41QgMVQA5Z4RKnX4rs0TizL7aopE/BhBEa6wI2DQVlW9\nRlfql+iQPSHaV74V2Bo0eQmPpVNM+pxvYMC8NQK/oQKBgQC8aoOCGZC5guzL+jDH\n+nxfM6p1z9fK+3R+ycoaKZOWVkH6MyjnQ31X8MWtDMa/l/etGKRzpOBRBDbkQ8Z3\ngskSU4nAiZ+tntl0CaUUHa4zcddQO/uJczemb5VqgMoFrg6HYyPPlGHzZUSy0TuV\nGyGWMMR7UZ/KfRRDGg93iLdIFA==\n-----END PRIVATE KEY-----\n"
	pubKey := "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx4Xnty/vrX9ai1JF7eTM\nh7BIgStQ/n3DZyb/8axtRTV15VKH0OoAreg0gv0AKIW7eKacCbUeV+/ko+9sYQ64\n9nfaXoMjJeTb38vcQSGkodx7aX664bizDYKmK40legET1IcsWTwWwmIUrvNq0YwP\nD0sdjIdrvEJQzXS0Gqm8Sq+nqA2FpbPs7lVmRdrhVD30aOnPIRT2HQf6ELZCssxy\nVlIpzYAwY3l6wXyf66AaXa9hao28BNuJCptBaf2UtQ8Ct/k4MSX7r7vFt8usIDBL\nvYL99LGRmK1TurTqWcrdqFmFF8vCGYpRFlAajYv5bCUTKIAkUAv9Wg0mJZtO0VY6\n2wIDAQAB\n-----END PUBLIC KEY-----\n"
	content := "模型训练需要花多长时间"

	sign, err := Sign([]byte(content), []byte(prvKey))

	if err != nil {
		t.Fatal(err)
		return
	}

	t.Log("sign 签名结果：", sign)

	res, err := RSAVerify(content, sign, []byte(pubKey))

	if err != nil {
		t.Fatal(err)
		return
	}

	t.Log("验签结果：", res)

}
